package nl.ypmits.utils.as3.math {
	import flash.events.ProgressEvent;
	import flash.geom.Point;

	/**
	 * @author Dave Lenz
	 */
	public class SimpleMath {

		private static const FLAG_PRECISION : String = "flagPrecision";
		private static const FLAG_ROUNDED : String = "flagRounded";
		private static const DEG_RAD : Number = Math.PI / 180;
		private static const RAD_DEG : Number = 180 / Math.PI;

		
		public static function roundNumber( num : Number, decimals : Number ) : Number {
			num = (num * decimals * 10);
			num = Math.round( num );
			num = num / (decimals * 10);
			
			return num;
		}

		
		public static function getPointFromAngleAndDistance( angle : Number, distance : Number ) : Point {
			var _x : Number = distance * Math.cos( angle * DEG_RAD );
			var _y : Number = distance * Math.sin( angle * DEG_RAD );
			
			return new Point( _x, _y );
		}

		
		static public function getPointOnQuadraticCurve(pct : Number, anchorPoint1 : Point, controlPoint : Point, anchorPoint2 : Point) : Point {
			var p : Point = new Point( );
			p.x = anchorPoint1.x + pct * (2 * (1 - pct) * (controlPoint.x - anchorPoint1.x) + pct * (anchorPoint2.x - anchorPoint1.x));
			p.y = anchorPoint1.y + pct * (2 * (1 - pct) * (controlPoint.y - anchorPoint1.y) + pct * (anchorPoint2.y - anchorPoint1.y));
			
			return p;
		}
		
		
		public static function convertProgressEventToPercentage( event : ProgressEvent, round : Boolean = true ) : Number {
			var p : Number;
			if( round ) {
				p = Math.round( ( event.bytesLoaded / event.bytesTotal ) * 100 );
			} else {
				p = ( event.bytesLoaded / event.bytesTotal ) * 100;
			}
			return p;
		}

		
		public static function getDistance( p1 : Point, p2 : Point ) : Number {
			var ddx : Number = p1.x - p2.x;
			var ddy : Number = p1.y - p2.y;
			var dd : Number = Math.sqrt( (ddx * ddx) + (ddy * ddy) );
			
			return dd;
		}

		
		public static function getAngle( p1 : Point, p2 : Point ) : Number {
			var adx : Number = p1.x - p2.x;
			var ady : Number = p1.y - p2.y;
			var ar : Number = -Math.atan2( adx, ady ) / DEG_RAD;
			
			return ar;
		}

		
		/**
		 * @author Dave Lenz
		 * 
		 * @param minNum default 0 The minimum Number
		 * @param maxNum default 0 The maximum Number
		 * @param flag default SimpleMath.FLAG_ROUNDED The flag can be used to retrieve precision or rounded results ('FLAG_ROUNDED' or 'FLAG_PRECISION'
		 * TODO Dit moet nog getest worden
		 * 
		 * @return Number A random number between two given numbers
		 */
		public static function getRandomNumberBetween( minNum : Number = 0, maxNum : Number = 0, flag : String = "flagPrecision" ) : Number {
			var precalc : Number = Math.random() * (maxNum - minNum) + minNum;
			var calc : Number;
			if( flag == SimpleMath.FLAG_ROUNDED ) {
				calc = Math.floor( precalc );
			} else if ( flag == SimpleMath.FLAG_PRECISION ) {
				calc = precalc;
			}
			
			return Math.random() * (maxNum - minNum) + minNum;
		};

		
		/**
		 * Converts degrees to radians and returns the radians
		 * 
		 * @param pDegrees Number The degree-number you want to convert to radians
		 */
		public static function degreesToRadians( pDegrees : Number ) : Number {			
			return pDegrees * DEG_RAD;
		}

		
		/**
		 * Converts radians to degrees and returns the degrees
		 * 
		 * @param pRadians Number The radian-number you want to convert to degrees
		 */
		public static function radiansToDegrees(pRadians : Number) : Number {
			return pRadians * RAD_DEG;
		}
		
		
		/**
		 * Makes sure a certain number is nicely in it's 'bounds'.
		 * When it goes over the edge it will return the edge-number
		 */
		public static function setBounds(value : Number, min : Number, max : Number) : Number 
		{
			return Math.min( Math.max( value, min ), max );
		}
	}
}